6.2.13 镜像散列值(摘要)

从Docker 1.10版本开始,镜像就是一系列松耦合的独立层的集合。

镜像本身就是一个配置对象,其中包含了镜像层的列表以及一些元数据信息。

镜像层才是实际数据存储的地方(比如文件等,镜像层之间是完全独立的,并没有从属于某个镜像集合的概念)。

镜像的唯一标识是一个加密ID,即配置对象本身的散列值。每个镜像层也由一个加密ID区分,其值为镜像层本身内容的散列值。

这意味着修改镜像的内容或其中任意的镜像层,都会导致加密散列值的变化。所以,镜像和其镜像层都是不可变的,任何改动都能很轻松地被辨别。

这就是所谓的 内容散列(Content Hash)

到目前为止,事情都很简单。但是接下来的内容就有点儿复杂了。

在推送和拉取镜像的时候,都会对镜像层进行压缩来节省网络带宽以及仓库二进制存储空间。

但是压缩会改变镜像内容,这意味着镜像的内容散列值在推送或者拉取操作之后,会与镜像内容不相符!这显然是个问题。

例如,在推送镜像层到Docker Hub的时候,Docker Hub会尝试确认接收到的镜像没有在传输过程中被篡改。为了完成校验,Docker Hub会根据镜像层重新计算散列值,并与原散列值进行比较。因为镜像在传输过程中被压缩(发生了改变),所以散列值的校验也会失败。

为避免该问题,每个镜像层同时会包含一个分发散列值(Distribution Hash)。这是一个压缩版镜像的散列值,当从镜像仓库服务拉取或者推送镜像的时候,其中就包含了分发散列值,该散列值会用于校验拉取的镜像是否被篡改过。

这个内容寻址存储模型极大地提升了镜像的安全性,因为在拉取和推送操作后提供了一种方式来确保镜像和镜像层数据是一致的。该模型也解决了随机生成镜像和镜像层ID这种方式可能导致的ID冲突问题。

results matching ""

    No results matching ""